
package Tri;

import java.util.ArrayList;
import metier.Personne;

/**
 *
 * @author epulapp
 * Classe utilisé lors des recherches
 */
public class Search {

    public static int compteurAmisTraverser = 0;

    
/**
 * Fonction permettant la recherche d'un invidu à l'aide d'un pseudo
 * 
 * Recherche faite à l'aide du parcours en BFS (en largeur)
 * 
 * Paramètres : liste : la liste de personne du réseau
 *              pseudo : le pseudo de la personne à chercher
 *              chercheur : la personne lançant cette recherche 
 */
    public static boolean searchByPseudoBFS(ArrayList<Personne> liste, int pseudo, Personne chercheur) {
        //initialisation de la liste de recherche
        //on mettra dedans toutes les personnes à vérifier si c'est celle que l'on recherche
        ArrayList<Personne> toSearch = new ArrayList<Personne>();

        //on remet à non visité tous les éléments de notre liste de personne
        int taille = liste.size();
        for (int i = 0; i < taille; i++) {
            liste.get(i).setVisited(false);
        }

        //aVerif contiendra la personne que l'on recherche
        Personne aVerif = chercheur;
        //tt
        //on ajoute la première personne à vérifier : celle qui demande la recherche
        toSearch.add(aVerif);

        while (!toSearch.isEmpty())//tant que la liste de recherche n'est pas vide
        {
            compteurAmisTraverser++;
            aVerif = toSearch.get(0);//on vérifie toujour le premier de la liste

            if (aVerif.getPseudo() != pseudo) //si le pseudo de a n'est pas celui recherché
            {
                //on marque a comme visité
                aVerif.setVisited(true);

                //on ajoute tous les amis de a dans notre liste de recherche
                int[] amis = aVerif.getAmis();

                for (int j = 0; j < amis.length; j++) {
                    //si l'amis n'a pas encore été visité on l'ajoute dans la liste
                    if (liste.get(amis[j]).isVisited() == false) {
                        toSearch.add(liste.get(amis[j]));
                    }
                    //sinon il a soit déjà été visité soit il est dans la liste => on ne fait rien.
                }

                //et on enleve a de notre liste de recherche donc le premier élément de la liste ne sera pas le même
                toSearch.remove(aVerif);
            } else //si le pseudo est celui qu'on recherche, on vide la liste pour sortir de la boucle
            {
                break;
            }
        }

        //si la dernière personne vérifié à la sortie du while a le même pseudo que celle recherchee alors on retourne la personne       
        if (aVerif.getPseudo() == pseudo) {
            System.out.println("trouvée : ");
            return true;

        } else {
            System.out.println("Personne non trouvée !");
            return false;

        }
    }

    
/**
 * Fonction permettant la recherche d'un invidu à l'aide d'un pseudo
 * 
 * Recherche faite à l'aide du parcours en DFS (en profondeur)
 * 
 * Paramètres : liste : la liste de personne du réseau
 *              pseudo : le pseudo de la personne à chercher
 *              chercheur : la personne lançant cette recherche 
 */
    
    
    public static boolean searchByPseudoDFS(ArrayList<Personne> liste, int pseudo, Personne chercheur) {
        //on remet à non visité tous les éléments de notre liste de personne
        int taille = liste.size();
        for (int i = 0; i < taille; i++) {
            liste.get(i).setVisited(false);
        }

        Personne p = pseudoDFS(liste, pseudo, chercheur);
        if (p.getPseudo() == pseudo) {
            System.out.println("trouvée : ");
            return true;
        } else {
            System.out.println("Personne non trouvée !");
            return false;
        }

    }

/**
* Fonction utilisée dans la recherche par DFS d'une personne à partir d'un pseudo 
* Utilisée en récursivité elle retourne la personne que l'on recherche si on passe par cette personne lors du parcours de la liste
* 
* paramètres : liste : la liste du réseau
*               pseudo : le pseudo de la personne à chercher
*               chercheur : la personne lançant la recherche
 */
    
    
    public static Personne pseudoDFS(ArrayList<Personne> liste, int pseudo, Personne chercheur) {
        Personne aVerif = chercheur;
        //on vérifie chaque élément voisin de chercheur
        //on lance la recherche DFS si l'amis n'est pas celui recherché
        int[] amis = aVerif.getAmis();

        int j = 0;
        while (j < amis.length) {
            //si l'amis n'a pas encore été visité on lance la recherche à partir de cette personne
            if (!liste.get(amis[j]).isVisited()) {
                aVerif.setVisited(true);
                if (liste.get(amis[j]).getPseudo() != pseudo) {
                    Personne p = pseudoDFS(liste, pseudo, liste.get(amis[j]));
                    return p;
                } else {
                    Personne t = liste.get(amis[j]);
                    return t;
                }
            }
            j++;

        }
        if (j == amis.length - 1) {
            return aVerif;
        }

        return aVerif;
    }
    
/**
 * Fonction lançant la recherche de toutes les personnes ayant des intêrets en commun avec la personne lançant la recherche
 * fonction utilisant le parcours BFS d'une liste
 * 
 * paramètres : la liste de personne du réseau
 *              chercheur : la personne lançant la recherche
 */
    
    public static ArrayList<Personne> searchByInterestBFS(ArrayList<Personne> liste, Personne chercheur) {
        //initialisation de la liste de recherche
        //on mettra dedans toutes les personnes à vérifier si c'est celle que l'on recherche
        ArrayList<Personne> find = new ArrayList<Personne>();
        String interetCherch;
        String interetVerif;
        //on remet à non visité tous les éléments de notre liste de personne
        int taille = liste.size();
        for (int i = 0; i < taille; i++) {
            liste.get(i).setVisited(false);
        }
        interetCherch = chercheur.getCentresConcat();
        for (int i = 0; i < taille - 1; i++) {
            if (!liste.get(i).isVisited()) {
                liste.get(i).setVisited(true);
                interetVerif = liste.get(i).getCentresConcat();
                if (interetCherch.equals(interetVerif)) {
                    find.add(liste.get(i));
                }
            }
        }
        return find;
    }

/**
 * Fonction lançant la recherche de toutes les personnes ayant des intêrets en commun avec la personne lançant la recherche
 * fonction utilisant le parcours DFS d'une liste
 * 
 * paramètres : la liste de personne du réseau
 *              chercheur : la personne lançant la recherche
 */
    
    public static Personne searchByInterestDFS(ArrayList<Personne> liste, Personne chercheur) { //on remet à non visité tous les éléments      de notre liste de personne 
        int taille = liste.size();
        for (int i = 0; i < taille; i++) {
            liste.get(i).setVisited(false);
        }
        Personne find = interestDFS(liste, chercheur);
        System.out.println(find);
        return find;

    }

    public static Personne interestDFS(ArrayList<Personne> liste, Personne chercheur) {
        String interets = chercheur.getCentresConcat();
        int[] amis = chercheur.getAmis();
        int j = 1;
        int cmp = 0;
        ArrayList<Personne> res = new ArrayList<Personne>();
        if (amis.length > 0) {
            while (j < amis.length) {
                if (!liste.get(amis[j]).isVisited()) {
                    liste.get(j).setVisited(true);
                    if (liste.get(j).getCentresConcat().equals(interets)) {
                        res.add(liste.get(j));
                       //s interestDFS(liste, liste.get(j));
                    }
                    else{
                    interestDFS(liste, liste.get(j));
                    System.out.println(liste.get(j).getNom() + " " + cmp++);
                    }
                }
                j++;
            }
        }
        return null;
       
    }
}
